
#include "udp_server.hpp"
#include <unordered_map>
#include <fstream>
#include <memory>
#include <signal.h>
using namespace server;

std::unordered_map<std::string, std::string> dict; // 字典
std::string dicttxt = "./dict.txt";                // 配置文件
std::string sep = ":";                             // 分隔符

// 未来不同的udp服务器其实就是在这里不一样。业务逻辑的处理不一样。
void serverfunc(int sockfd, std::string message, uint16_t clientport, std::string clinetip)
{
    // 打印接受的数据
    std::cout << clinetip << "[" << clientport << "]#" << message << std::endl;

    struct sockaddr_in client_addr;
    bzero(&client_addr,sizeof(client_addr));
    client_addr.sin_family = AF_INET;
    client_addr.sin_port = htons(clientport);
    client_addr.sin_addr.s_addr = inet_addr(clinetip.c_str());
 
    std::string retstr;
    if (dict.end() == dict.find(message))
    {
        retstr = "没找到！！";
    }
    else
    {
        retstr = dict[message];
    }

    sendto(sockfd, retstr.c_str(), retstr.size(), 0, (struct sockaddr *)&client_addr, sizeof(client_addr));
    std::cout << "发送数据： " << retstr << std::endl;
}

static bool catline(const std::string &line, std::string *key, std::string *value)
{
    auto pos = line.find(sep);
    if (pos == std::string::npos)
    {
        return false;
    }
    *key = line.substr(0, pos);
    *value = line.substr(pos + sep.size());
    return true;
}

void dictinit()
{
    std::ifstream in(dicttxt, std::ios::binary);
    if (!in.is_open())
    {
        // 打开失败
        std::cerr << "open file" << dicttxt << "error!!" << std::endl;
        exit(OPEN_ERROE);
    }
    std::string line, key, value;
    while (getline(in, line))
    {
        if (catline(line, &key, &value))
        {
            dict.insert(make_pair(key, value));
        }
        else
        {
            std::cout << "catline error" << std::endl;
            exit(CATLINE_ERROR);
        }
    }
    in.close();
}

// test
void printdict()
{
    for (auto e : dict)
    {
        std::cout << e.first << "#" << e.second << std::endl;
    }
}

// 使用手册
void usage(char *proc)
{
    std::cout << "Usage: \n\t" << proc << " local_port\n\n";
}
void handler(int sig)
{
    //支持热加载。
    dictinit();
    std::cout<<"字典更新完成"<<std::endl;
}

// 未来将来吧 ，Ip和Port 传进来，我们需要用到，命令行参数。
// 使用 ："./server local_ip local_port"
int main(int argc, char *argv[])
{
    signal(3, handler);
    if (argc != 2)
    {
        usage(argv[0]);
        exit(USAGE_ERROR);
    }
    // //port
    uint16_t port = atoi(argv[1]);
    // uint16_t port = 10002;

    dictinit();
    // printdict();

    std::unique_ptr<udpServer> us(new udpServer(serverfunc, port)); // 不用传入ip，使用0.0.0.0
    us->initServer();
    us->startServer();

    return 0;
}

// #include "udp_server.hpp"
// #include <memory>

// using namespace std;
// using namespace Server;

// static void Usage(string proc)
// {
//     cout << "\nUsage:\n\t" << proc << " local_port\n\n";
// }

// void handlerMessage(string clientip, uint16_t clientport, string message)
// {
//     //就可以对message进行特定的业务处理，而不关心message怎么来的 ---- server通信和业务逻辑解耦！
// }

// // ./udpServer port
// int main(int argc, char *argv[])
// {
//     if(argc != 2)
//     {
//         Usage(argv[0]);
//         exit(USAGE_ERR);
//     }
//     uint16_t port = atoi(argv[1]);
//     // string ip = argv[1];

//     std::unique_ptr<udpServer> usvr(new udpServer(handlerMessage, port));

//     usvr->initServer();
//     usvr->start();

//     return 0;
// }

// #include "udp_server.hpp"

// int main()
// {

//     uint32_t ip = 12345; //对应 57.48.0.0
//     struct _ip
//     {
//         unsigned char p1;
//         unsigned char p2;
//         unsigned char p3;
//         unsigned char p4;
//     };

//     std::string str_ip;
//     str_ip += std::to_string((int)((struct _ip *)&ip)->p1);
//     str_ip += '.';
//     str_ip += std::to_string((int)((struct _ip *)&ip)->p2);

//     str_ip += '.';
//     str_ip += std::to_string((int)((struct _ip *)&ip)->p3);

//     str_ip += '.';
//     str_ip += std::to_string((int)((struct _ip *)&ip)->p4);

//     std::cout << str_ip << std::endl;

//     struct _ip
//     {
//         unsigned char p1;
//         unsigned char p2;
//         unsigned char p3;
//         unsigned char p4;
//     };

//     std::string str_ip = "57.48.0.0";
//     int posc = 0;
//     auto pos = str_ip.find('.',0);
//     int p1 = atoi(str_ip.substr(posc, pos).c_str());

//     posc = pos;
//     pos = str_ip.find('.', posc + 1);
//     int p2 = atoi(str_ip.substr(posc+1, pos).c_str());

//     posc = pos;
//     pos = str_ip.find('.', posc + 1);
//     int p3 = atoi(str_ip.substr(posc+1, pos).c_str());

//     posc = pos;
//     pos = str_ip.find('.', posc + 1);
//     int p4 = atoi(str_ip.substr(posc+1, pos).c_str());

//     struct _ip tmp ;
//     tmp.p1 = p1;
//     tmp.p2 = p2;
//     tmp.p3 = p3;
//     tmp.p4 = p4;

//     std::cout<<*((uint32_t*)&tmp)<<std::endl;//12345
// }


// #include <stdio.h>
// #include<iostream>
// #include<unistd.h>
// #include <sys/types.h>
// #include <unistd.h>
// #include<signal.h>



// void func(int sig)
// {
//     sleep(3);
//     std::cout<<"捕捉到信号 2 "<<std::endl;   
// }
// int main()
// {
//     while(1)
//     {
//         signal(2, func);
//         std::cout<<getpid()<<std::endl;
//         sleep(1);
//     }

//     return 0;
// }